package com.newtouch.cq.base.starter.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.newtouch.cq.base.starter.business.entity.SysRole;
import com.newtouch.cq.base.starter.business.mapper.BaseSysRoleMapper;
import com.newtouch.cq.base.starter.business.model.UserDetailsImpl;
import com.newtouch.cq.base.starter.business.model.dto.SysRoleAddDTO;
import com.newtouch.cq.base.starter.business.model.dto.SysRoleMenuDTO;
import com.newtouch.cq.base.starter.business.model.dto.SysRolePageDTO;
import com.newtouch.cq.base.starter.business.model.dto.SysRoleUpdDTO;
import com.newtouch.cq.base.starter.business.service.IBaseSysRoleMenuService;
import com.newtouch.cq.base.starter.business.service.IBaseSysRoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.newtouch.cq.base.starter.business.service.IBaseSysUserRoleService;
import com.newtouch.cq.base.starter.lang.util.CurrentUserUtil;
import com.newtouch.cq.lang.em.BaseExceptionEnum;
import com.newtouch.cq.lang.em.StatusEnum;
import com.newtouch.cq.lang.exception.MccBizException;
import com.newtouch.cq.lang.result.MccPageResult;
import com.newtouch.cq.lang.util.DateUtils;
import com.newtouch.cq.lang.util.LogUtil;
import com.newtouch.cq.mybatis.util.DbUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * <p>
 * 系统角色表 服务实现类
 * </p>
 *
 * @author Alex
 * @since 2021-08-02
 */
@Service
public class BaseSysRoleServiceImpl extends ServiceImpl<BaseSysRoleMapper, SysRole> implements IBaseSysRoleService {

    @Resource
    private IBaseSysRoleMenuService roleMenuService;

    @Resource
    private IBaseSysUserRoleService userRoleService;

    private Log log = LogFactory.get(BaseSysRoleServiceImpl.class);

    @Override
    public void add(SysRoleAddDTO dto) {
        UserDetailsImpl operator = CurrentUserUtil.userOrThrow();
        SysRole role = new SysRole();
        BeanUtil.copyProperties(dto, role, CopyOptions.create().ignoreNullValue());
        role.setStatus(StatusEnum.VALID);
        role.setCreateId(operator.getId());
        role.setCreateTime(DateUtils.localDateTime());
        role.setUpdateId(operator.getId());
        role.setUpdateTime(DateUtils.localDateTime());
        baseMapper.insert(role);
    }

    @Override
    public void update(long id, SysRoleUpdDTO dto) {
        long operatorId = CurrentUserUtil.userIdOrThrow();
        DbUtil.containId(baseMapper,id,log);
        SysRole role = new SysRole();
        BeanUtil.copyProperties(dto, role, CopyOptions.create().ignoreNullValue());
        role.setId(id);
        role.setUpdateId(operatorId);
        role.setUpdateTime(DateUtils.localDateTime());
        baseMapper.updateById(role);
    }

    @Override
    public MccPageResult<SysRole> pageList(SysRolePageDTO dto) {
        LambdaQueryWrapper<SysRole> wrapper = Wrappers.lambdaQuery(SysRole.class)
                .ne(SysRole::getStatus, StatusEnum.DELETE.getValue())
                .like(StrUtil.isNotEmpty(dto.getRoleName()), SysRole::getRoleName, dto.getRoleName())
                .like(StrUtil.isNotEmpty(dto.getRoleCode()), SysRole::getRoleCode, dto.getRoleCode());
        Page<SysRole> rolePage = baseMapper.selectPage(dto.buildPage(), wrapper);
        return MccPageResult.success(rolePage);
    }

    @Override
    public void roleMenuUpd(SysRoleMenuDTO dto) {
        roleMenuService.deleteByRoleIdAndSave(dto);
    }

    @Override
    public List<SysRole> userRole(long userId) {
        return baseMapper.getUserRole(userId);
    }

    @Override
    @Transactional
    public void roleDel(long id) {
        long operatorId = CurrentUserUtil.userIdOrThrow();
        if (userRoleService.userHasRole(operatorId, id)) {
            LogUtil.error(log, BaseExceptionEnum.FAIL, "不能删除自己的角色");
            throw new MccBizException(BaseExceptionEnum.FAIL).setMessage("不能删除自己的角色");
        }
        SysRole roleDel = new SysRole();
        roleDel.setId(id);
        roleDel.setStatus(StatusEnum.DELETE);
        roleDel.setUpdateId(operatorId);
        roleDel.setUpdateTime(DateUtils.localDateTime());
        baseMapper.updateById(roleDel);

        userRoleService.deleteByRoleId(id);
    }

    @Override
    public List<SysRole> enableList() {
        LambdaQueryWrapper<SysRole> wrapper = Wrappers.lambdaQuery(SysRole.class).eq(SysRole::getStatus, StatusEnum.VALID.getValue());
        return baseMapper.selectList(wrapper);
    }
}
